package com.gis.util;

import com.gis.beans;
import lombok.extern.slf4j.Slf4j;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;

import java.text.DecimalFormat;
import java.util.ArrayList;

/**
 * @author leon
 * @ClassName UtilsClass.java
 * @createTime 2021年09月26日 11:57:00
 */
@Slf4j
public class UtilsClass {
    public static beans getNewbeans(beans aisMaster){

        beans aisSlave = new beans();

        aisSlave.setMmsi(aisMaster.getMmsi());
        aisSlave.setUnixTime(aisMaster.getUnixTime());
        aisSlave.setSpeed(aisMaster.getSpeed());
        aisSlave.setLon_d(aisMaster.getLon_d());
        aisSlave.setLat_d(aisMaster.getLat_d());

        return aisSlave;
    }

    /**
     * 求解两个坐标之间的距离
     *
     * @param gpsFrom   第一个点坐标
     * @param gpsTo     第二个点坐标
     * @param ellipsoid 使用的坐标系
     * @return
     */
    public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid) {
        //创建GeodeticCalculator，调用计算方法，传入坐标系、经纬度用于计算距离
        GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);

        return geoCurve.getEllipsoidalDistance();
    }


    /**
     * 求得距离
     */
    public static double getStance(beans ais1, beans ais2) {


        GlobalCoordinates source = new GlobalCoordinates(ais1.getLat_d(), ais2.getLon_d());
        GlobalCoordinates target = new GlobalCoordinates(ais2.getLat_d(), ais2.getLon_d());


        double meter = getDistanceMeter(source, target, Ellipsoid.WGS84);

        return meter;
    }

    /**
     * 获取小数点后几位有效数字
     * @param i 小数点后几位
     * @param j 小数double
     * @return
     */
    public static double getDecimal(int i,double j){
        if (i == 2){

            DecimalFormat df = new DecimalFormat("#.##");
            return Double.parseDouble(df.format(j));
        }else if (i == 6){
            DecimalFormat df = new DecimalFormat("#.######");
            return Double.parseDouble(df.format(j));
        }
        return 0;
    }

    /**
     * 插值
     * @param ais1
     * @param ais2
     * @return
     */
    public static ArrayList<beans> insertPoint(beans ais1, beans ais2) {

        //获得实际距离
        double stance = getStance(ais1, ais2);
        //按照距离进行插值，需要插入点的个数
        double number = Math.floor(stance / 200) - 1;

        //实例化一个列表，将所有添加的数据放大集合中
        ArrayList<beans> aisInsertList = new ArrayList<>();

        //插入的点放入集合中
        for (int i = 1; i <= number; i++) {

            //speed就应该是大于ais1，并且小于ais2
            double speed = getDecimal(2,ais1.getSpeed() + (ais2.getSpeed() - ais1.getSpeed()) * i / (number + 1));

            //插入点的lat和lon
            double lat = getDecimal(6,ais1.getLat_d() + (ais2.getLat_d() - ais1.getLat_d()) * i / (number + 1));
            double lon = getDecimal(6,ais1.getLon_d() + (ais2.getLon_d() - ais1.getLon_d()) * i / (number + 1));

            //时间
            //Math.round():Double类型转换为Long
            //long转换为double,(double)long;
            Long unixTime = Math.round(ais1.getUnixTime() + (ais2.getUnixTime() - ais1.getUnixTime()) * i / (number + 1));

            //course,rot等其他字段，都采用ais1的
            String mmsi = ais1.getMmsi();
            //封装到aisData中
            beans aisData = new beans(mmsi, unixTime, speed, lon,lat);

            //输出插值得到的点
            log.info("插值得到的点：" + aisData);
            //放到列表中
            aisInsertList.add(aisData);

        }

        //返回列表
        return aisInsertList;
    }

}
